using IQIGame.Onigao.Game;
using System;
using UnityEngine;

namespace IQIGame.Onigao.GamePlay
{
    public static class GameMathUtil
    {
        public static Rect GetRectRangeV2(float centerx, float centerz, float halfSize)
        {
            float xMin = centerx - halfSize;
            float zMin = centerz - halfSize;
            float width = halfSize * 2;
            float height = halfSize * 2;
            return new Rect(xMin, zMin, width, height);
        }

        public static Rect GetRectRangeV2(Vector3 centerPos, float halfSize)
        {
            float xMin = centerPos.x - halfSize;
            float zMin = centerPos.z - halfSize;
            float width = halfSize * 2;
            float height = halfSize * 2;
            return new Rect(xMin, zMin, width, height);
        }

        #region 旋转值转int（存储格式）
        public static Quaternion IntEuler2Quaternion(int intEuler)
        {
            int x = intEuler >> 18;  // Extract the x rotation
            int y = (intEuler >> 9) & 511; // Extract the y rotation
            int z = intEuler & 511; // Extract the z rotation
            return Quaternion.Euler(x, y, z);
        }
        /// <summary>
        /// 将intEuler转换成Vector3 euler，注意转换出来的Vector3依然是纪录的欧拉角信息
        /// </summary>
        /// <param name="intEuler"></param>
        /// <returns>euler vector3</returns>
        public static Vector3 IntEulerToVector3(int intEuler)
        {
            Vector3 v3;
            v3.x = intEuler >> 18;  // Extract the x rotation
            v3.y = (intEuler >> 9) & 511; // Extract the y rotation
            v3.z = intEuler & 511; // Extract the z rotation
            return v3;
        }

        /// <summary>
        /// 将intEuler转换成方向矢量
        /// </summary>
        /// <param name="intEuler"></param>
        /// <returns>归一化的方向矢量</returns>
        public static Vector3 IntEulerToDirection(int intEuler)
        {
            int x = intEuler >> 18;  // Extract the x rotation
            int y = (intEuler >> 9) & 511; // Extract the y rotation
            int z = intEuler & 511; // Extract the z rotation
            Quaternion rotation = Quaternion.Euler(x, y, z);
            return rotation * Vector3.forward;
        }

        public static int Quaternion2Int(Quaternion q)
        {
            var euler = q.eulerAngles;

            int x = (int)(euler.x) % 360;
            int y = (int)(euler.y) % 360;
            int z = (int)(euler.z) % 360;
            return (x << 18) | (y << 9) | z;
        }

        public static int GetRotationYFromInt(int intEuler)
        {
            var y = (intEuler >> 9) & 511; // Extract the y rotation
            return y;
        }
        #endregion 旋转值转int（存储格式）

        public static float LogicValue2Float(float x)
        {
            return x / GameGlobalConst.LogicPosScale;
        }

        public static float Float2LogicValue(float x)
        {
            return x * GameGlobalConst.LogicPosScale;
        }

        public static Vector3 LogicPos2UnityPosV2(float x, float z)
        {
            return new Vector3(x / GameGlobalConst.LogicPosScale, z / GameGlobalConst.LogicPosScale);
        }

        public static Vector3 LogicPos2UnityPos(float x, float y, float z)
        {
            return new Vector3(x / GameGlobalConst.LogicPosScale, y / GameGlobalConst.LogicPosScale, z / GameGlobalConst.LogicPosScale);
        }

        public static Vector3 LogicPos2UnityPos(Framework.Vector3Int logicPos)
        {
            return new Vector3((float)logicPos.x / GameGlobalConst.LogicPosScale,
                (float)logicPos.y / GameGlobalConst.LogicPosScale,
                (float)logicPos.z / GameGlobalConst.LogicPosScale);
        }

        public static Vector3 UnityPos2LogicPos(Vector3 position)
        {
            return new Vector3(position.x * GameGlobalConst.LogicPosScale,
                position.y * GameGlobalConst.LogicPosScale,
                position.z * GameGlobalConst.LogicPosScale);
        }

        public static Framework.Vector3Int UnityPos2LogicPosInt(Vector3 position)
        {
            return new Framework.Vector3Int((int)Math.Round(position.x * GameGlobalConst.LogicPosScale),
                (int)Math.Round(position.y * GameGlobalConst.LogicPosScale),
                (int)Math.Round(position.z * GameGlobalConst.LogicPosScale));
        }

        public static Framework.Vector3Int UnityPos2LogicPosInt(float x, float y, float z)
        {
            return new Framework.Vector3Int((int)Math.Round(x * GameGlobalConst.LogicPosScale),
                (int)Math.Round(y * GameGlobalConst.LogicPosScale),
                (int)Math.Round(z * GameGlobalConst.LogicPosScale));
        }

        public static Vector3 Rect2OBBSize(Game.RectInt rect, float height)
        {
            return new Vector3((float)rect.Width / GameGlobalConst.LogicPosScale,
                height,
                (float)rect.Height / GameGlobalConst.LogicPosScale);
        }

        public static Vector2 Rect2OBBSizeV2(Game.RectInt rect)
        {
            return new Vector2((float)rect.Width / GameGlobalConst.LogicPosScale,
                (float)rect.Height / GameGlobalConst.LogicPosScale);
        }

        public static Vector3 GetRectOffset(Game.RectInt rect)
        {
            return new Vector3((float)rect.X / GameGlobalConst.LogicPosScale,
                0,
                (float)rect.Y / GameGlobalConst.LogicPosScale);
        }

        public static Vector2 GetRectOffsetV2(Game.RectInt rect)
        {
            return new Vector2((float)rect.X / GameGlobalConst.LogicPosScale,
                (float)rect.Y / GameGlobalConst.LogicPosScale);
        }


        //判断两个角度小于某个值
        public static bool IsAxisRotationInRange(float eulerAngle1, float eulerAngle2, float range)
        {
            // 将欧拉角转换到0到360度之间的值
            eulerAngle1 = WrapAngle(eulerAngle1);
            eulerAngle2 = WrapAngle(eulerAngle2);

            // 计算两个欧拉角的差值
            float angleDifference = Mathf.Abs(WrapAngle(eulerAngle1 - eulerAngle2));

            // 检查差值是否小于45度
            return angleDifference < range;
        }

        public static float WrapAngle(float angle)
        {
            // 将角度限制在0到360度之间
            angle %= 360f;

            if (angle < 0)
            {
                angle += 360f;
            }

            return angle;
        }

        /// <summary>
        /// 计算两个角度的差值，负数表示左旋转，正数表示右旋转
        /// </summary>
        /// <param name="srcAngle">原始值</param>
        /// <param name="targetAngle">目标值</param>
        /// <returns></returns>
        public static float AngleDifference(float srcAngle, float targetAngle)
        {
            float diff = (targetAngle - srcAngle + 180) % 360 - 180;
            return diff < -180 ? diff + 360 : diff;
        }

        public static void LogicObstacleInfo2Meter()
        {

        }

        /// <summary>
        /// 把 阻挡信息（配置）+ 实体旋转 转换成合适的矩形阻挡大小
        /// </summary>
        /// <param name="entityPos"></param>
        /// <param name="info"></param>
        /// <param name="center"></param>
        /// <param name="halfBounds"></param>
        /// <param name="rotationY"></param>
        public static void ObstacleInfo2RecastBox(Vector3 entityPos, ObstacleInfo info, float[] center, float[] halfBounds, float rotationY)
        {
            Vector3 finalPos;
            if (info.x == 0 && info.y == 0)
            {
                finalPos = entityPos;
            }
            else
            {
                var obstacleX = LogicValue2Float(info.x);
                var obstacleZ = LogicValue2Float(info.y);
                if (rotationY == 0)
                {
                    finalPos = entityPos + new Vector3(obstacleX, 0, obstacleZ);
                }
                else
                {
                    var rotatedOffset = RotateOffset(new Vector3(obstacleX, 0, obstacleZ), rotationY);
                    finalPos = entityPos + rotatedOffset;
                }
            }
            center[0] = -finalPos.x;
            center[1] = entityPos.y + (float)info.height / 2;
            center[2] = finalPos.z;
            halfBounds[0] = (float)info.rectW / 2;
            halfBounds[1] = (float)info.height / 2;
            halfBounds[2] = (float)info.rectH / 2;
        }

        public static Vector3 RotateOffset(Vector3 offset, float rotationY)
        {
            // 将角度转换为弧度
            float radian = rotationY * MathLogic.Deg2Rad;
            // 计算旋转矩阵
            double cos = Math.Cos(radian);
            double sin = Math.Sin(radian);
            // 应用旋转矩阵
            double newX = offset.x * cos + offset.z * sin;
            double newZ = -offset.x * sin + offset.z * cos;
            // 返回旋转后的向量
            return new Vector3((float)newX, offset.y, (float)newZ);
        }
    }
}
